/* 
 * File:   ThreadPool.cpp
 * Author: Lance
 * 
 * Created on September 30, 2012, 12:32 AM
 */

#include "ThreadPool.h"

/**
 * Function that the threads run;
 */
void * threadWorker(void * workerData)
{
	WorkerData * data = (WorkerData*) workerData;
	while(1)
	{
		sem_wait(data->workToDo);
		ClientHandler * handler = data->pool->dequeue();
		handler->handle();
	}
}

ThreadPool::ThreadPool() {
	poolSize = 10;	//default pool size
	initializeSemaphores();
	initializeThreads();
}

ThreadPool::ThreadPool(int poolSize)
{
	this->poolSize = poolSize;
	initializeSemaphores();
	initializeThreads();
}

void ThreadPool::initializeSemaphores()
{
	sem_init(&queueUnlocked, 0, 1);
	sem_init(&workToDo, 0, 0);
}

void ThreadPool::initializeThreads()
{
	for(int i = 0; i < poolSize; i++)
	{
		pthread_t * thread = new pthread_t;
		WorkerData * threadData = new WorkerData(this, &workToDo);
		pthread_create(thread, NULL, &threadWorker, threadData);
	}
}

ThreadPool::ThreadPool(const ThreadPool& orig) {
}

ThreadPool::~ThreadPool() {
}

void ThreadPool::enqueue(ClientHandler* handler)
{
	sem_wait(&queueUnlocked);
	clientQueue.push(handler);
	sem_post(&queueUnlocked);
	sem_post(&workToDo);
}

ClientHandler * ThreadPool::dequeue()
{
	sem_wait(&queueUnlocked);
	ClientHandler * handler = clientQueue.front();
	clientQueue.pop();
	sem_post(&queueUnlocked);
	return handler;
}


